//###############
//FILE : NameInitSession.java
//WRITER : Daniel Lowengrub, daniel_i_l, 320687098
//EXERCISE : oop ex3 2011
//DESCRIPTION:
//See below
//###############
package oop.ex3.protocol.sessions;

import oop.ex3.protocol.messages.ContainFileMsg;
import oop.ex3.protocol.messages.BeginMsg;
import oop.ex3.protocol.messages.ContainNameServerMsg;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import oop.ex3.communication.SocketAddress;
import oop.ex3.exceptions.InvalidMessageException;

/**
 * Handle a FM session initialization. First decide whether to respond with welcome or done.
 * Then update the databases if necessary.
 * @author daniel
 */
public class NameInitSession extends NameToFileSession{
    private SocketAddress _fileAddress;
    private ArrayList<SocketAddress> _nameServers;
    private ArrayList<String> _fileNames;
    private ArrayList<SocketAddress> _recognizedFileServers;
    private boolean _newFileServer;

    /**
	 * Create a new session.
	 */
    public NameInitSession() {
        super(new BeginMsg());
    }

    /**
     * Set the list of file names to update.
     * @param fileNames The file name list.
     */
    public void setFileNames(ArrayList<String> fileNames) {
        _fileNames = fileNames;
    }

    /**
     * Set the list of NSs to update.
     * @param nameServers The list of NSs.
     */
    public void setNameServers(ArrayList<SocketAddress> nameServers) {
        _nameServers = nameServers;
    }

    /**
     * Set the list of FM that we know about.
     * @param fileServers The FM list.
     */
    public void setRecognizedFileServers(ArrayList<SocketAddress> fileServers) {
        _recognizedFileServers = fileServers;
    }

    /**
     * Get the address of the FM that initialized this request.
     * @return The FM address.
     */
    public SocketAddress getFileAddress() {
        return _fileAddress;
    }

    /**
     * Check if this FM is new to us.
     * @return True iff the FM was new.
     */
    public boolean newFileServer() {
        return _newFileServer;
    }

    @Override
    protected boolean specExecuteSession(DataInputStream inputStream, DataOutputStream outputStream)
            throws IOException, InvalidMessageException {

        BeginMsg begin = new BeginMsg();
        begin.receive(inputStream);
        _fileAddress = new SocketAddress(begin.getIp(), begin.getPort());


        if (_recognizedFileServers.contains(_fileAddress)) {
            _done.send(outputStream);
            _newFileServer = false;
            return true;
        }

        _newFileServer = true;


        _welcome.send(outputStream);
        ContainFileMsg containFile = new ContainFileMsg();

        //get file names
        while(!_endList.matchHeader(inputStream)) {
            containFile.receive(inputStream);
            _fileNames.add(containFile.getFileName());
            _done.send(outputStream);
        }

        _endList.receive(inputStream);
        _done.send(outputStream);

        ContainNameServerMsg containName = new ContainNameServerMsg();

        //get name servers
        while(!_endList.matchHeader(inputStream)) {
            containName.receive(inputStream);
            _nameServers.add(containName.getAddress());
            _done.send(outputStream);
        }

        _endList.receive(inputStream);
        _done.send(outputStream);

        return true;
    }


}
